package com.coszero.common.utils.update;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;

import com.azhon.appupdate.manager.DownloadManager;
import com.coszero.utils.app.ApkInfoUtils;
import com.coszero.utils.utils.DataCleanManager;
import com.coszero.common.config.RequestCode;
import com.coszero.common.dialog.CommonDialogView;
import com.coszero.commonlib.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;


/**
 * @author zy
 * @date 2015-5-26
 * @version 1
 */
public class UpdateManager {
    /*谷歌play商店包名*/
    public final static String GOOGLE_PLAY = "com.android.vending";
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    /**
     * Checks if the app has permission to write to device storage
     * <p>
     * If the app does not has permission then the user will be prompted to grant permissions
     *
     * @param activity
     */
    public void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }


    private final String TAG = "UpdateMageger";

    /* 下载中 */
    private static final int DOWNLOAD = 1;
    /* 下载结束 */
    private final int DOWNLOAD_FINISH = 2;
    private final int MSG_SHOW_DOWNLOAD_DIALOG = 3;
    private final int MSG_CHECK_CLIENT_VERSION = 4;

    private final int MSG_CHECK_FAIILED = 6;
    /* 下载保存路径 */
    private String mSavePath = "/storage/emulated/0/khmiDownload/";
    /* 记录进度条数量 */
    private int progress;
    /*记录数值文件存储量*/
    private double mSize;
    /*记录已下载完成的储量*/
    private double currentSize;

    /* 是否取消更新 */
    private boolean cancelUpdate = false;

    private static Activity mContext;
    private Builder downloadDialog;
    /* 更新进度条 */
    private ProgressBar mProgress;
    /*更新進度*/
    private TextView title, totalSize, loadedSize, loadRate;
    private Dialog mDownloadDialog;
    private boolean isXMLDownloadSucceed = false;
    @Deprecated
    @SuppressWarnings({"unchecked", "deprecation"})
    public ProgressDialog progressDialog = null;
    private long speed;

    private String downLoadPath = "http://192.168.0.201/apk/Wandoujia_2007190_web_seo_baidu_homepage.apk";
    private String apkName = "Wandoujia_2007190_web_seo_baidu_homepage.apk";
    private String mApkSize;

    LayoutInflater inflater;
    View view;
    private Handler workHandler;
    public static UpdateManager instance;

    public UpdateManager() {
        instance = new UpdateManager();
    }


    /*
     * 启动到应用商店app详情界面
     *
     * @param appPkg 目标App的包名
     * @param marketPkg 应用商店包名 ,如果为""则由系统弹出应用商店列表供用户选择,否则调转到目标市场的应用详情界面
     */
    public static void launchAppDetail(Context mContext, String appPkg, String marketPkg) {
        try {
            if (TextUtils.isEmpty(appPkg)) {
                return;
            }
            Uri uri = Uri.parse("market://details?id=" + appPkg);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            if (!TextUtils.isEmpty(marketPkg)) {
                intent.setPackage(marketPkg);
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 判断应用市场是否存在的方法
     *
     * @param context
     * @param packageName 主流应用商店对应的包名
     * com.android.vending -----Google Play
     * com.tencent.android.qqdownloader -----应用宝
     * com.qihoo.appstore -----360手机助手
     * com.baidu.appsearch -----百度手机助
     * com.xiaomi.market -----小米应用商店
     * com.wandoujia.phoenix2 -----豌豆荚
     * com.huawei.appmarket -----华为应用市场
     * com.taobao.appcenter -----淘宝手机助手
     * com.hiapk.marketpho -----安卓市场
     * cn.goapk.market -----安智市场
     * @param context
     * @param packageName
     * @return
     */
    @Deprecated
    @SuppressWarnings({"unchecked", "deprecation"})
    public static boolean isAvilible(Context context, String packageName) {
        // 获取packagemanager
        final PackageManager packageManager = context.getPackageManager();
        // 获取所有已安装程序的包信息
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
        // 用于存储所有已安装程序的包名
        List pName = new ArrayList();
        // 从pinfo中将包名字取出
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pf = pinfo.get(i).packageName;
                pName.add(pf);
            }
        }
        // 判断pName中是否有目标程序的包名，有true，没有false
        return pName.contains(packageName);
    }

    public UpdateManager(final Activity context) {
        instance = this;
        mContext = context;
        inflater = LayoutInflater.from(mContext);
        view = inflater.inflate(R.layout.com_dialog_softupdate_progress, null);
        HandlerThread handlerThread = new HandlerThread("UpdateManager");
        handlerThread.start();
        workHandler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case MSG_SHOW_DOWNLOAD_DIALOG:
                        showDownloadDialog();
                        break;
                    case DOWNLOAD:
                        // 设置进度条位置
                        title.setText("正在更新" + "(" + progress + "%)");
                        String strCurrentSize = String.format("%.2fM", currentSize);
                        loadedSize.setText(strCurrentSize);
                        loadRate.setText(speed + "K/s");
                        mProgress.setProgress(progress);
                        break;
                    case DOWNLOAD_FINISH:
                        downloadApkThread.interrupt();
                        // 安装文件
                        openAPKFile(mContext);
                        break;
                    case MSG_CHECK_FAIILED:
                        Toast.makeText(mContext, "检测失败!", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            }
        };
    }


    /**
     * 显示软件下载对话框
     */
    public void showDownloadDialog() {
        mSize = Double.parseDouble(mApkSize);
        if (downloadDialog == null) {
            downloadDialog = new Builder(mContext);
        }
        // 给下载对话框增加进度条
        final LayoutInflater inflater = LayoutInflater.from(mContext);
        View v = inflater.inflate(R.layout.com_dialog_softupdate_progress, null);
        mProgress = v.findViewById(R.id.update_progress);
        title = v.findViewById(R.id.title);
        totalSize = v.findViewById(R.id.total_size);
        String strTotalSize = DataCleanManager.getFormatSize(Double.valueOf(mSize));
//        String strTotalSize = String.format("//%.2fM", mSize);
        totalSize.setText("/" + strTotalSize);
        loadedSize = v.findViewById(R.id.loaded_size);
        loadRate = v.findViewById(R.id.load_rate);
        downloadDialog.setView(v);
        // 取消更新
        /*downloadDialog.setNegativeButton(R.string.cancel, new OnClickListener()
        {
			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				dialog.dismiss();
				// 设置取消状态
				cancelUpdate = true;
				downloadApkThread.interrupt();
			}
		});*/
        mDownloadDialog = downloadDialog.create();
        mDownloadDialog.setCanceledOnTouchOutside(false);
        mDownloadDialog.show();
        // 下载文件
        downloadApk();

    }

    DownloadApkThread downloadApkThread;

    /**
     * 下载apk文件
     */
    private void downloadApk() {
        // 启动新线程下载软件
        downloadApkThread = new DownloadApkThread();
        downloadApkThread.start();
    }


    /**
     * 下载文件线程
     *
     * @author zy
     * @date 2015-5-26
     */
    private class DownloadApkThread extends Thread {
        private long nowTimeStamp, lastTimeStamp;
        private long time;

        @Override
        public void run() {
            try {
                // 判断SD卡是否存在，并且是否具有读写权限
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    cancelUpdate = false;
                    // 获得存储卡的路径
                    String sdpath = Environment.getExternalStorageDirectory() + "/";
                    mSavePath = sdpath + "khmiDownload";

                    URL url = new URL(downLoadPath);
                    // 创建连接
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.connect();
                    // 获取文件大小
                    float length = conn.getContentLength();
                    mSize = (length / 1024.0) / 1024.0;
                    // 创建输入流
                    InputStream is = conn.getInputStream();
                    File file = new File(sdpath);
                    // 判断文件目录是否存在
                    if (!file.exists()) {
                        file.mkdir();
                    }
                    if (!new File(mSavePath).exists()) {
                        new File(mSavePath).mkdirs();
                    }
                    File apkFile = new File(mSavePath, apkName);
                    FileOutputStream fos = new FileOutputStream(apkFile);
                    int count = 0;
                    // 缓存
                    byte[] buf = new byte[1024];

                    //记录第一次开始下载时时间
                    lastTimeStamp = System.currentTimeMillis();
                    // 写入到文件中
                    do {
                        int numread = is.read(buf);
                        count += numread;
                        // 计算进度条位置
                        progress = (int) (((float) count / length) * 100);
                        currentSize = ((float) count / 1024.0) / 1024.0;
                        nowTimeStamp = System.currentTimeMillis();
                        time = (nowTimeStamp - lastTimeStamp);
                        if (time > 1000) {

                            if (time > 0) {
                                speed = (numread * 1000 / 8) / (time);
                                lastTimeStamp = nowTimeStamp;
                                // 更新进度
                                workHandler.sendEmptyMessage(DOWNLOAD);
                            }
                        }
                        // 更新进度
                        workHandler.sendEmptyMessage(DOWNLOAD);
                        if (numread <= 0) {
                            // 下载完成
                            workHandler.sendEmptyMessage(DOWNLOAD_FINISH);
                            break;
                        }
                        // 写入文件
                        fos.write(buf, 0, numread);
                    } while (!cancelUpdate);// 点击取消就停止下载.
                    fos.close();
                    is.close();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 取消下载对话框显示
            mDownloadDialog.dismiss();
        }
    }

    /**
     * 安装APK文件
     */
    private void installApk() {
        File apkfile = new File(mSavePath, apkName);
        if (!apkfile.exists()) {
            return;
        }
        // 通过Intent安装APK文件
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
        mContext.startActivity(i);
    }


    public void openAPKFile(final Activity mContext) {
        // 核心是下面几句代码
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            File apkFile = new File(mSavePath, apkName);
            //兼容7.0
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                //兼容8.0
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    boolean hasInstallPermission = mContext.getPackageManager().canRequestPackageInstalls();
                    /*if (!hasInstallPermission) {
                        CommonDialogView.showMsg(mContext.getString(R.string.update_permission), new CommonDialogView.DialogClickListener() {
                            @RequiresApi(api = Build.VERSION_CODES.O)
                            @Override
                            public void doConfirm() {
                                startInstallPermissionSettingActivity(mContext);
                            }

                            @Override
                            public void doCancel() {
                            }
                        });
                        return;
                    } else {*/
                    Uri contentUri = FileProvider.getUriForFile(mContext, ApkInfoUtils.getPackageName(mContext) + ".down.fileProvider", apkFile);
                    intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
//                    }
                } else {
                    Uri contentUri = FileProvider.getUriForFile(mContext, ApkInfoUtils.getPackageName(mContext) + ".down.fileProvider", apkFile);
                    intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
                }
            } else {
                intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
            if (mContext.getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
                mContext.startActivity(intent);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }


    Runnable xmlRunnable = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (!isXMLDownloadSucceed) {
                mContext.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        if (progressDialog != null) {
                            progressDialog.dismiss();
                        }
                        Toast.makeText(mContext, "检测失败，请检查网络设置！", Toast.LENGTH_LONG).show();
                    }
                });
            } else {
                isXMLDownloadSucceed = false;
            }
        }
    };

    private boolean checkStoragePermission(Activity context) {
        int ret = ActivityCompat.checkSelfPermission(context, Manifest.permission
                .READ_EXTERNAL_STORAGE);
        int ret1 = ActivityCompat.checkSelfPermission(context, Manifest.permission
                .WRITE_EXTERNAL_STORAGE);
        if (ret1 != PackageManager.PERMISSION_GRANTED || ret != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
            return false;
        } else {
            return true;
        }
    }


    public void showDownLoadDialog() {
        Message msg = new Message();
        msg.what = MSG_SHOW_DOWNLOAD_DIALOG;
        workHandler.sendMessage(msg);
    }

    /**
     * 显示新版本内容
     */
    public void showUpdateContentDialog(final Activity baseActivity, boolean isUpdateMust, String tipsInfo, String content, final String size, final String path, int currentVersionCode) {
        CommonDialogView.showMsgDialog(tipsInfo, isUpdateMust ? "" : "稍后再说", isUpdateMust ? "立即升级" : "更新",
                new CommonDialogView.DialogClickListener() {
                    @Override
                    public void doConfirm() {
                        //检查商店，有应用商店使用商店升级
                        if (UpdateManager.isAvilible(baseActivity, UpdateManager.GOOGLE_PLAY)) {
                            UpdateManager.launchAppDetail(baseActivity, ApkInfoUtils.getPackageName(baseActivity), UpdateManager.GOOGLE_PLAY);
                        } else {
                            //没有检查到goolePlay商店，直接进行下载
                            DownloadManager manager = DownloadManager.getInstance(baseActivity);
                            apkName = getFileName(downLoadPath);
                            manager.setApkName(apkName)
                                    .setApkUrl(downLoadPath)
                                    .setSmallIcon(0)
                                    .download();
                    /*if (checkStoragePermission(baseActivity)) {
                        downLoadPath = path;
                        mApkSize = size;
                        apkName = getFileName(downLoadPath);
                        showDownLoadDialog();
                    }*/
                        }
                    }

                    @Override
                    public void doCancel() {
//                PreferencesHelper.save("newVersion", currentVersionCode);
                    }
                });

    }


    public String getFileName(String pathandname) {
        if (!TextUtils.isEmpty(pathandname)) {
            int start = pathandname.lastIndexOf("/");
            int end = pathandname.lastIndexOf(".");
            if (start != -1 && end != -1) {
                return pathandname.substring(start + 1, end) + ".apk";
            } else {
                return "merchant" + ".apk";
            }
        } else {
            return "merchant" + ".apk";
        }

    }

    /**
     * 跳转到设置-允许安装未知来源-页面
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity(Activity context) {
        Uri packageURI = Uri.parse("package:" + ApkInfoUtils.getPackageName(context));
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivityForResult(intent, RequestCode.REQUEST_CODE_UNKNOWN_APP);

    }


    @Deprecated
    @SuppressWarnings({"unchecked", "deprecation"})
    public static boolean isNeddUpdate(Context context, String versionCode) {
        try {
            int nowVersion = 0;
            try {
                PackageManager packageManager = context.getPackageManager();
                PackageInfo packageInfo = packageManager.getPackageInfo(
                        context.getPackageName(), 0);
                nowVersion = packageInfo.versionCode;
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
                return false;
            }
            int version = Integer.parseInt(versionCode);
            return version > nowVersion;
        } catch (Exception e) {
            return false;
        }
    }


    public static UpdateManager getInstance() {
        return instance;
    }

    public static void setInstance(UpdateManager instance) {
        UpdateManager.instance = instance;
    }
}
